[

define array->get(from::integer, to, by::integer=1)::array => {
	.size == 0 ? return(array)
	#to === null ? #to = .size 
	local(get) = array
	loop(-from=#from, -to=integer(#to), -by=#by)
		#get->insert(.get(loop_count))
	/loop
	return(#get)
}

define array->seek(position::integer,default) => {
	#position > .size || #position < 0 ? return #default
	return(.get(#position))
}

define array->geteven()::array => {
	.size < 2 ? return(array)
	return(.get(2,null,2))
}

define array->getodd()::array => {
	.size < 1 ? return(array)
	return(.get(1,null,2))
}

/*
	array(1,2,3,4,5,6,7,8,9,10)->get(2,6)
	'<br>'
	array(1,2,3,4,5,6,7,8,9,10)->get(5,null)
	'<br>'
	array(1,2,3,4,5,6,7,8,9,10)->get(1,null,3)
	'<br>'
	array(1,2,3,4,5,6,7,8,9,10)->geteven
	'<br>'
	array(1,2,3,4,5,6,7,8,9,10)->getodd
*/


define array->random => .size == 0 ? return void | return .get(math_random(1,.size))
//array('a','b','c','d','e','f')->random


define array->setsize(size::integer,empty=void) => {
  .reserve(#size)
  loop(#size)
    .insert(#empty->asCopy)
  /loop
}

/*
var('array') = array
$array->setsize(10)
$array->get(3) = 'a'
$array->get(8) = 'b'
$array
*/

// ============================================

define array->each(code::capture) => {
  loop(.size)
    this = .get(loop_count)
    #code->invoke
    .get(loop_count) = this
  /loop

}

/*
var('array') = array(1,'a','c'=date)
$array->each({^ this->asString + ' ' ^})
'<br>'
var('array') = array(1,2,3)
$array->each({ this *= 5 })
$array
*/

// ============================================

define array->join(delimiter, op = \+) => {
  .isEmpty ? return(string)

  local(c=0,join=null)
  .foreach => { 
    #c++ == 0
      ? #join = #1
      | #join = #op(#op(#join,#delimiter),#1)
  }
  return(#join)
}

define array->add => .join(0,\+)
define array->sub => .join(0,\-)
define array->mult => .join(1,\*)
define array->div => .join(1,\/)
define array->mean => .add / .size->asDecimal
define array->median => {
  local(temp) = .asArray
  #temp->sort
  #temp->size->isOdd
    ? return( #temp->get(.size / 2 + 1)->asDecimal )
    | return( #temp->get(.size / 2, .size / 2 + 1)->mean )
}

/*
array(2,4,6)->add
'<br>'
array(10,2,1)->sub
'<br>'
array(2,4,6)->mult
'<br>'
array(96,4,2)->div
'<br>'
array(2,4,6)->mean
'<br>'
array(4,2,6,10,8)->median
'<br>'
array(4,2,8,6)->median
*/

// ===== PATCHES =====

/* opted for adding an offset, idea from staticarray
define array->find(value::any) => {
	local(output) = array
	.foreach =>	{ #1->type == 'pair'
					? (#value == #1->name ? #output->insert(#1))
					| (#value == #1 ? #output->insert(#1))
				}
	return(#output)
}
// array('a' = 1, 'a', 'b')->find('a')
*/

/*
define array->find(value::any, offset::integer=1) => {
	local(output) = array
	with cnt in #offset to .size
	where #value == .get(#cnt) || ('pair,keyword' >> .get(#cnt)->type && #value == .get(#cnt)->name) 
	do #output->insert(.get(#cnt))
	return(#output)
}
//array('a' = 1, 'a', 'b')->find('a',2)


define array->contains(value::any) => {
	.foreach =>	{ 'pair,keyword' >> #1->type
					? (#value == #1->name ? return(true))
					| (#value == #1 ? return(true))
				}
	return(false)
}
// array('abc'=1) >> 'abc'
// array('abc'=1)->contains('abc')

*/

define array->+(rhs::string)::string => .asString + #rhs
// array+string

define array->get(k::pair_compare) => {
    local(p) = .find(#k)
    #p->size > 0 ? return(#p->first) | return(void)
}


define array->columns(-maxcols::integer=0,-maxrows::integer=0,-empty=void,-fill::boolean=false,-vertical::boolean=false,-horizontal::boolean=true)::array => {

	// optional: -maxcols=n, -maxrows=n constrain the maximum # of rows and/or columns
	// optional: -vertical OR -horizontal, if the info should be displayed vertically or horizontally
	//
	// defaults: -horizontal, even columns and rows

	local(size) = .size
	#size == 0 ? return array

	// check for out of bounds
	if(!#fill)
		#maxcols > #size ? #maxcols = #size
		#maxrows > #size ? #maxrows = #size
	/if

	// figure out if max passed, if not, assign default value
	#maxcols < 1 && #maxrows < 1 ? #maxcols = #size->sqrt->floor->asInteger

	// calc maxcols
	#maxcols < 1 ? #maxcols = (#size->asDecimal / #maxrows->asDecimal)->ceil->asInteger
	
	// calc maxrows
	#maxrows < 1 ? #maxrows = (#size->asDecimal / #maxcols->asDecimal)->ceil->asInteger

	// shrink size to datasize, throw away maxrows
	!#fill && (#maxrows->asDecimal - (#size->asDecimal / #maxcols->asDecimal)) >= 1.0 ? #maxrows = (#size->asDecimal / #maxcols->asDecimal)->ceil->asInteger
	
	// build empty array
	local(out) = array->setsize(#maxrows,array->setsize(#maxcols,#empty)&)&;
	
	// direction to output data, horizontal or vertical
	local(direction) = (#vertical ? 'vertical' | 'horizontal')

	// ptrs in array
	local(rowcc = carousel_count(1,#maxrows), colcc = carousel_count(1,#maxcols), row = #rowcc->asInteger, col = #colcc->asInteger)

	// iterate through the data and format it
	iterate(self)

		// insert element
		#out->get(#row)->get(#col) = loop_value
		
		if(#direction == 'horizontal')
			#col = #colcc->asInteger
			if(#col == 1)
				#row = #rowcc->asInteger
				#row == 1 ? loop_abort
			/if
		else // vertical
			#row = #rowcc->asInteger
			if(#row == 1)
				#col = #colcc->asInteger
				#col == 1 ? loop_abort
			/if
		/if
	
	/iterate

	return #out

}

/*

[var:'array' = (array:'a','b','c','d','e','f','g','h','i')]

<pre>
<b>-=['['] E X A M P L E S [']']=-</b>

<b>Raw:</b>

[iterate: $array, var:'cell'][$cell]	[/iterate]


<b>Horizontal:</b>
[iterate: $array->columns, var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Vertical:</b>
[iterate: $array->columns(-vertical), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Horizontal -maxcols=2:</b>
[iterate: $array->columns(-maxcols=2), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Horizontal -maxrows=2:</b>
[iterate: $array->columns(-maxrows=2), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Horizontal -maxcols=2, -maxrows=2:</b>
[iterate: $array->columns(-maxcols=2, -maxrows=2), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Vertical -maxcols=2:</b>
[iterate: $array->columns(-vertical, -maxcols=2), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Vertical -maxrows=2:</b>
[iterate: $array->columns(-vertical, -maxrows=2), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]


<b>Vertical -maxcols=2, -maxrows=2:</b>
[iterate: $array->columns(-vertical, -maxcols=2, -maxrows=2), var:'row']
[iterate: $row, var:'cell'][$cell]	[/iterate][/iterate]

</pre>

*/

define array->asMap::map=> {
  local(map) = map
  .forEach => {
    #map->insert(#1)
  }
  return #map
}

]